home *** CD-ROM | disk | FTP | other *** search
- Subject: v09i024: Z80 macro cross-assembler, Part01/02
- Newsgroups: mod.sources
- Approved: rs@mirror.TMC.COM
-
- Submitted by: pyrnj!vu-vlsi!colin (Colin Kelley)
- Mod.sources: Volume 9, Issue 24
- Archive-name: zmac/Part01
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # Makefile zmac.y mio.c zmac.1 zdis.1
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'Makefile'" '(642 characters)'
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- # Makefile to make z80 macro assembler.
- CFLAGS =
-
- all: zmac zdis
-
- zmac: y.tab.o mio.o
- cc $(CFLAGS) -o zmac y.tab.o mio.o
-
- y.tab.c: zmac.y
- yacc zmac.y
-
- zdis: zdis.o
- cc $(CFLAGS) -o zdis zdis.o
-
- install:
- install -s zmac /usr/local/bin
- install -s zdis /usr/local/bin
-
- install_man:
- cp zmac.1 /usr/man/manl/zmac.l
- cp zdis.1 /usr/man/manl/zdis.l
-
- clean:
- rm -f zdis.o zmac.o mio.o y.tab.c y.tab.o a.out core
-
- shar: zmac.shar.1 zmac.shar.2
-
- zmac.shar.1: Makefile zmac.y mio.c zmac.1 zdis.1
- shar -vc Makefile zmac.y mio.c zmac.1 zdis.1 > zmac.shar.1
-
- zmac.shar.2: zdis.c serial.z serial.hex
- shar -vc zdis.c serial.z serial.hex > zmac.shar.2
- SHAR_EOF
- if test 642 -ne "`wc -c < 'Makefile'`"
- then
- echo shar: error transmitting "'Makefile'" '(should have been 642 characters)'
- fi
- chmod +x 'Makefile'
- fi # end of overwriting check
- echo shar: extracting "'zmac.y'" '(50295 characters)'
- if test -f 'zmac.y'
- then
- echo shar: will not over-write existing file "'zmac.y'"
- else
- cat << \SHAR_EOF > 'zmac.y'
- %{
- /*
- * zmac -- macro cross-assembler for the Zilog Z80 microprocessor
- *
- * Bruce Norskog 4/78
- *
- * Last modification 1-18-87 by cdk
- * This assembler is modeled after the Intel 8080 macro cross-assembler
- * for the Intel 8080 by Ken Borgendale. The major features are:
- * 1. Full macro capabilities
- * 2. Conditional assembly
- * 3. A very flexible set of listing options and pseudo-ops
- * 4. Symbol table output
- * 5. Error report
- * 6. Elimination of sequential searching
- * 7. Commenting of source
- * 8. Facilities for system definiton files
- *
- * Revision History:
- *
- * jrp 3-8-82 Converted to run on Vax, updated syntax to conform better
- * to the Zilog standard.
- *
- * jrp 3-15-82 Added underscore as a character type in the lex table
- * 'numpart' (0x5F).
- *
- * Changed maximum number of characters in a label to 15
- * from 7. Note that 'putsymtab' uses this value inside
- * of a quoted string, so we use 15.
- *
- * jrp 2-15-83 Fixed 'getlocal' to return better local labels. It used
- * to crash after 6 invocations.
- *
- * jrp 6-7-83 Fixed bug in the ADD IX,... instruction.
- *
- * jrp 5-11-84 Added code to print unused labels out with the symbol table
- * Also sped up the macro processor by using stdio.
- *
- * jrp 5-22-84 Added include files ala ormac
- *
- * jrp 8-27-84 Added PHASE/DEPHASE commands
- *
- * cdk 9-20-86 Converted to run on a Pyramid. This meant changing yylval
- * to be a %union, and then putting in the appropriate
- * typecasts where ints are pointers are used interchangeably.
- * The current version still probably won't run on machines where
- * sizeof(int) != sizeof(char *).
- * Also changed emit() to use varargs, and got rid of the
- * old style = in front of yacc action code.
- * -Colin Kelley vu-vlsi!colin
- *
- * cdk 10-2-86 Added some more typecasts to keep lint a little happier.
- * Removed several unused variables. Changed most vars
- * declared as char to int, since many of them were being
- * compared with -1! I still don't know what's going on with
- * est[][] being malloc'd and free'd everywhere...it looks pretty
- * fishy...
- *
- * cdk 1-18-87 Added MIO code to emulate 'mfile' using malloc()'d memory.
- * This was needed to get the code to work when compiled under
- * MSC 4.0 on a PC, and it's probably faster anyway.
- *
- * cdk 2-5-87 Added 'cmp' as a synonym for 'cp', 'jmp' as a synonym for
- * 'jp', and added tolerance of accumulator specification for arithmetic
- * and logical instructions. (For example, 'or a,12' is now accepted,
- * same as 'or 12'.)
- */
-
-
- #define MIO /* use emulation routines from mio.c */
-
- #include <stdio.h>
- #ifdef MSDOS
- #include <fcntl.h>
- #else
- #include <sys/file.h> /* for open() calls */
- #endif
-
- #ifdef vax11c
- #define unlink(filename) delete(filename)
- #endif
-
- #ifdef MIO
- FILE *mfopen();
- #else
- #define mfopen(filename,mode) fopen(filename,mode)
- #define mfclose(filename,mode) fclose(filename,mode)
- #define mfputc(c,f) putc(c,f)
- #define mfgetc(f) getc(f)
- #define mfseek(f,loc,origin) fseek(f,loc,origin)
- #define mfread(ptr,size,nitems,f) fread(ptr,size,nitems,f)
- #define mfwrite(ptr,size,nitems,f) fread(ptr,size,nitems,f)
- #endif /* MIO */
-
- /*
- * DEBUG turns on pass reporting.
- * Macro debug and Token debug enables.
- #define DEBUG
- #define M_DEBUG
- #define T_DEBUG
- */
-
- #define ITEMTABLESIZE 2000
- #define TEMPBUFSIZE 200
- #define LINEBUFFERSIZE 200
- #define EMITBUFFERSIZE 200
- #define MAXSYMBOLSIZE 15
- #define IFSTACKSIZE 20
- #define MAXIFS 150
- #define TITLELEN 50
- #define BINPERLINE 16
- #define PARMMAX 25
- #define MAXEXP 25
- #define SYMMAJIC 07203
- #define NEST_IN 8
-
-
- #define loop for(;;)
-
- yyerror(err)
- char *err;
- {} /* we will do our own error printing */
-
- struct item {
- char *i_string;
- int i_value;
- int i_token;
- int i_uses;
- };
-
- FILE *fout,
- *fbuf,
- *fin[NEST_IN],
- *now_file ;
-
- char *malloc() ;
-
- int pass2; /*set when pass one completed*/
- int dollarsign ; /* location counter */
- int olddollar ; /* kept to put out binary */
-
- /* program counter save for PHASE/DEPHASE */
- int phdollar, phbegin, phaseflag ;
-
- char *src_name[NEST_IN] ;
- int linein[NEST_IN] ;
- int now_in ;
-
-
-
- #define bflag 0 /* balance error */
- #define eflag 1 /* expression error */
- #define fflag 2 /* format error */
- #define iflag 3 /* bad digits */
- #define mflag 4 /* multiply defined */
- #define pflag 5 /* phase error */
- #define uflag 6 /* undeclared used */
- #define vflag 7 /* value out of range */
- #define oflag 8 /* phase/dephase error */
-
- #define FLAGS 9 /* number of flags */
-
- char err[FLAGS];
- int keeperr[FLAGS];
- char errlet[]="BEFIMPUVO";
- char *errname[]={
- "Balance",
- "Expression",
- "Format",
- "Digit",
- "Mult. def.",
- "Phase",
- "Undeclared",
- "Value",
- "Phase/Dephase",
- };
-
-
- char linebuf[LINEBUFFERSIZE];
- char *lineptr;
- char *linemax = &linebuf[LINEBUFFERSIZE];
-
- char outbin[BINPERLINE];
- char *outbinp = outbin;
- char *outbinm = &outbin[BINPERLINE];
-
- char emitbuf[EMITBUFFERSIZE];
- char *emitptr;
-
- char ifstack[IFSTACKSIZE];
- char *ifptr;
- char *ifstmax = &ifstack[IFSTACKSIZE-1];
-
-
- char expif[MAXIFS];
- char *expifp;
- char *expifmax = &expif[MAXIFS];
-
- char hexadec[] = "0123456789ABCDEF" ;
- char *expstack[MAXEXP];
- int expptr;
-
-
- int nitems;
- int linecnt;
- int nbytes;
- int invented;
-
-
- char tempbuf[TEMPBUFSIZE];
- char *tempmax = &tempbuf[TEMPBUFSIZE-1];
-
- char inmlex;
- char arg_flag;
- char quoteflag;
- int parm_number;
- int exp_number;
- char symlong[] = "Symbol too long";
-
- int disp;
- #define FLOC PARMMAX
- #define TEMPNUM PARMMAX+1
- char **est;
- char **est2;
-
- char *floc;
- int mfptr;
- FILE *mfile;
-
- char *writesyms;
-
-
- char *title;
- char titlespace[TITLELEN];
- char *timp,*ctime();
- char *sourcef;
- char src[15];
- char bin[15];
- char mtmp[15];
- char listf[15];
-
- char bopt = 1,
- edef = 1,
- eopt = 1,
- fdef = 0,
- fopt = 0,
- gdef = 1,
- gopt = 1,
- iopt = 0 , /* list include files */
- lstoff = 0,
- lston = 0, /* flag to force listing on */
- lopt = 0,
- mdef = 0,
- mopt = 0,
- nopt = 1 , /* line numbers on as default */
- oopt = 0,
- popt = 1, /* form feed as default page eject */
- sopt = 0, /* turn on symbol table listing */
- topt = 1;
- saveopt;
-
- char xeq_flag = 0;
- int xeq;
-
- long now;
- int line;
- int page = 1;
-
- struct stab {
- char t_name[MAXSYMBOLSIZE+1];
- int t_value;
- int t_token;
- };
-
- /*
- * push back character
- */
- int peekc;
-
-
- /*
- * add a character to the output line buffer
- */
- addtoline(ac)
- int ac;
- {
- /* check for EOF from stdio */
- if (ac == -1)
- ac = 0 ;
- if (inmlex)
- return(ac);
- if (lineptr >= linemax)
- error("line buffer overflow");
- *lineptr++ = ac;
- return(ac);
- }
-
- #include <varargs.h>
-
- /*
- * put values in buffer for outputing
- */
-
- /*VARARGS*/
- /*ARGSUSED*/
- emit(va_alist)
- va_dcl
- {
- register int bytes;
- va_list ap;
- va_start(ap);
-
- bytes = va_arg(ap,int);
-
- while (--bytes >= 0)
- if (emitptr >= &emitbuf[EMITBUFFERSIZE])
- error("emit buffer overflow");
- else {
- *emitptr++ = va_arg(ap,int);
- }
- va_end(ap);
- }
-
-
- emit1(opcode,regvalh,data16,type)
- int opcode,regvalh,data16,type;
- {
- if (regvalh & 0x8000) {
- if (type & 1 == 0 && (disp > 127 || disp < -128))
- err[vflag]++;
- switch(type) {
- case 0:
- if (opcode & 0x8000)
- emit(4, regvalh >> 8, opcode >> 8, disp, opcode);
- else
- emit(3, regvalh >> 8, opcode, disp);
- break;
- case 1:
- emit(2, regvalh >> 8, opcode);
- break;
- case 2:
- if (data16 > 255 || data16 < -128)
- err[vflag]++;
- emit(4, regvalh >> 8, opcode, disp, data16);
- break;
- case 5:
- emit(4, regvalh >> 8, opcode, data16, data16 >> 8);
- }
- } else
- switch(type) {
- case 0:
- if (opcode & 0100000)
- emit(2, opcode >> 8, opcode);
- else
- emit(1, opcode);
- break;
- case 1:
- if (opcode & 0100000)
- emit(2, opcode >> 8, opcode);
- else
- emit(1, opcode);
- break;
- case 2:
- if (data16 > 255 || data16 < -128)
- err[vflag]++;
- emit(2, opcode, data16);
- break;
- case 3:
- if (data16 >255 || data16 < -128)
- err[vflag]++;
- emit(2, opcode, data16);
- break;
- case 5:
- if (opcode & 0100000)
- emit(4, opcode >> 8, opcode, data16, data16 >> 8);
- else
- emit(3, opcode, data16, data16 >> 8);
- }
- }
-
-
-
-
- emitdad(rp1,rp2)
- int rp1,rp2;
- {
- if (rp1 & 0x8000)
- emit(2,rp1 >> 8, rp2 + 9);
- else
- emit(1,rp2 + 9);
- }
-
-
- emitjr(opcode,expr)
- int opcode,expr;
- {
- disp = expr - dollarsign - 2;
- if (disp > 127 || disp < -128)
- err[vflag]++;
- emit(2, opcode, disp);
- }
-
-
-
-
- /*
- * put out a byte of binary
- */
- putbin(v)
- {
- if(!pass2 || !bopt) return;
- *outbinp++ = v;
- if (outbinp >= outbinm) flushbin();
- }
-
-
-
- /*
- * output one line of binary in INTEL standard form
- */
- flushbin()
- {
- register char *p;
- register check;
-
- if (!pass2 || !bopt)
- return;
- nbytes += outbinp-outbin;
- if (check = outbinp-outbin) {
- putc(':', fbuf);
- puthex(check, fbuf);
- puthex(olddollar>>8, fbuf);
- puthex(olddollar, fbuf);
- puthex(0, fbuf);
- check += (olddollar >> 8) + olddollar;
- olddollar += (outbinp-outbin);
- for (p=outbin; p<outbinp; p++) {
- puthex(*p, fbuf);
- check += *p;
- }
- puthex(256-check, fbuf);
- putc('\n', fbuf);
- outbinp = outbin;
- }
- }
-
-
-
- /*
- * put out one byte of hex
- */
- puthex(byte, buf)
- char byte;
- FILE *buf;
- {
- putc(hexadec[(byte >> 4) & 017], buf);
- putc(hexadec[byte & 017], buf);
- }
-
- /*
- * put out a line of output -- also put out binary
- */
- list(optarg)
- int optarg;
- {
- register char * p;
- register int i;
- int lst;
-
- if (!expptr)
- linecnt++;
- addtoline('\0');
- if (pass2) {
- lst = iflist();
- if (lst) {
- lineout();
- if (nopt)
- fprintf(fout, "%4d:\t", linein[now_in]);
- puthex(optarg >> 8, fout);
- puthex(optarg, fout);
- fputs(" ", fout);
- for (p = emitbuf; (p < emitptr) && (p - emitbuf < 4); p++) {
- puthex(*p, fout);
- }
- for (i = 4 - (p-emitbuf); i > 0; i--)
- fputs(" ", fout);
- putc('\t', fout);
- fputs(linebuf, fout);
- }
-
- if (bopt) {
- for (p = emitbuf; p < emitptr; p++)
- putbin(*p);
- }
-
-
- p = emitbuf+4;
- while (lst && gopt && p < emitptr) {
- lineout();
- if (nopt) putc('\t', fout);
- fputs(" ", fout);
- for (i = 0; (i < 4) && (p < emitptr);i++) {
- puthex(*p, fout);
- p++;
- }
- putc('\n', fout);
- }
-
-
- lsterr2(lst);
- } else
- lsterr1();
- dollarsign += emitptr - emitbuf;
- emitptr = emitbuf;
- lineptr = linebuf;
- }
-
-
-
- /*
- * keep track of line numbers and put out headers as necessary
- */
- lineout()
- {
- if (line == 60) {
- if (popt)
- putc('\014', fout); /* send the form feed */
- else
- fputs("\n\n\n\n\n", fout);
- line = 0;
- }
- if (line == 0) {
- fprintf(fout, "\n\n%s %s\t%s\t Page %d\n\n\n",
- &timp[4], &timp[20], title, page++);
- line = 4;
- }
- line++;
- }
-
-
- /*
- * cause a page eject
- */
- eject()
- {
- if (pass2 && iflist()) {
- if (popt) {
- putc('\014', fout); /* send the form feed */
- } else {
- while (line < 65) {
- line++;
- putc('\n', fout);
- }
- }
- }
- line = 0;
- }
-
-
- /*
- * space n lines on the list file
- */
- space(n)
- {
- int i ;
- if (pass2 && iflist())
- for (i = 0; i<n; i++) {
- lineout();
- putc('\n', fout);
- }
- }
-
-
- /*
- * Error handling - pass 1
- */
- lsterr1() {
- register int i;
- if (topt)
- for (i = 0; i <= 4; i++)
- if (err[i]) {
- errorprt(i);
- err[i] = 0;
- }
- }
-
-
- /*
- * Error handling - pass 2.
- */
- lsterr2(lst)
- int lst;
- {
- register int i;
- for (i=0; i<FLAGS; i++)
- if (err[i]) {
- if (lst) {
- lineout();
- putc(errlet[i], fout);
- putc('\n', fout);
- }
- err[i] = 0;
- keeperr[i]++;
- if (i > 4 && topt)
- errorprt(i);
- }
-
- fflush(fout); /*to avoid putc(har) mix bug*/
- }
-
- /*
- * print diagnostic to error terminal
- */
- errorprt(errnum)
- int errnum;
- {
- fprintf(stderr,"%d: %s error\n%s\n",
- linecnt, errname[errnum], linebuf) ;
- fflush(stderr) ;
- return ;
- }
-
-
- /*
- * list without address -- for comments and if skipped lines
- */
- list1()
- {
- int lst;
-
- addtoline('\0');
- lineptr = linebuf;
- if (!expptr) linecnt++;
- if (pass2)
- if (lst = iflist()) {
- lineout();
- if (nopt)
- fprintf(fout, "%4d:\t", linein[now_in]);
- fprintf(fout, "\t\t%s", linebuf);
- lsterr2(lst);
- }
- else
- lsterr1();
- }
-
-
- /*
- * see if listing is desired
- */
- iflist()
- {
- register i, j;
-
- if (lston)
- return(1) ;
- if (lopt)
- return(0);
- if (*ifptr && !fopt)
- return(0);
- if (!lstoff && !expptr)
- return(1);
- j = 0;
- for (i=0; i<FLAGS; i++)
- if (err[i])
- j++;
- if (expptr)
- return(mopt || j);
- if (eopt && j)
- return(1);
- return(0);
- }
-
-
- %}
-
- %union {
- struct item *itemptr;
- int ival;
- char *cval;
- }
-
- %token <cval> STRING
- %token <itemptr> NOOPERAND
- %token <itemptr> ARITHC
- %token ADD
- %token <itemptr> LOGICAL
- %token <itemptr> BIT
- %token CALL
- %token <itemptr> INCDEC
- %token <itemptr> DJNZ
- %token EX
- %token <itemptr> IM
- %token PHASE
- %token DEPHASE
- %token <itemptr> IN
- %token JP
- %token <itemptr> JR
- %token LD
- %token <itemptr> OUT
- %token <itemptr> PUSHPOP
- %token <itemptr> RET
- %token <itemptr> SHIFT
- %token <itemptr> RST
- %token <itemptr> REGNAME
- %token <itemptr> ACC
- %token <itemptr> C
- %token <itemptr> RP
- %token <itemptr> HL
- %token <itemptr> INDEX
- %token <itemptr> AF
- %token <itemptr> SP
- %token <itemptr> MISCREG
- %token F
- %token <itemptr> COND
- %token <itemptr> SPCOND
- %token <ival> NUMBER
- %token <itemptr> UNDECLARED
- %token END
- %token ORG
- %token DEFB
- %token DEFS
- %token DEFW
- %token EQU
- %token DEFL
- %token <itemptr> LABEL
- %token <itemptr> EQUATED
- %token <itemptr> WASEQUATED
- %token <itemptr> DEFLED
- %token <itemptr> MULTDEF
- %token <ival> MOD
- %token <ival> SHL
- %token <ival> SHR
- %token <ival> NOT
- %token IF
- %token ENDIF
- %token <itemptr> ARGPSEUDO
- %token <itemptr> LIST
- %token <itemptr> MINMAX
- %token MACRO
- %token <itemptr> MNAME
- %token <itemptr> OLDMNAME
- %token ARG
- %token ENDM
- %token MPARM
- %token <ival> ONECHAR
- %token <ival> TWOCHAR
-
- %type <itemptr> label.part symbol
- %type <ival> reg evenreg realreg mem pushable bcdesp bcdehlsp mar condition
- %type <ival> spcondition parenexpr expression lxexpression
-
- %left '|' '^'
- %left '&'
- %nonassoc NOT
- %left '+' '-'
- %left '*' '/' MOD SHL SHR
- %left UNARY
- %%
-
- %{
- char *cp;
- int i;
- %}
-
- program:
- statements
- |
- error { error("file bad"); }
- ;
-
-
- statements:
- statement
- |
- statements statement
- |
- statements error {
- fprintf(stderr,"statement error\n");
- err[fflag]++;
- quoteflag = 0;
- while(yychar != '\n' && yychar != '\0') yychar = yylex();
- list(dollarsign);
- yyclearin;yyerrok;
- }
- ;
-
-
- statement:
- label.part '\n' {
- if ($1) list(dollarsign);
- else list1();
- }
- |
- label.part operation '\n' {
- list(dollarsign);
- }
- |
- symbol EQU expression '\n' {
- switch($1->i_token) {
- case UNDECLARED: case WASEQUATED:
- $1->i_token = EQUATED;
- $1->i_value = $3;
- break;
- default:
- err[mflag]++;
- $1->i_token = MULTDEF;
- }
- list($3);
- }
- |
- symbol DEFL expression '\n' {
- switch($1->i_token) {
- case UNDECLARED: case DEFLED:
- $1->i_token = DEFLED;
- $1->i_value = $3;
- break;
- default:
- err[mflag]++;
- $1->i_token = MULTDEF;
- }
- list($3);
- }
- |
- symbol MINMAX expression ',' expression '\n' {
- switch ($1->i_token) {
- case UNDECLARED: case DEFLED:
- $1->i_token = DEFLED;
- if ($2->i_value) /* max */
- list($1->i_value = ($3 > $5? $3:$5));
- else list($1->i_value = ($3 < $5? $3:$5));
- break;
- default:
- err[mflag]++;
- $1->i_token = MULTDEF;
- list($1->i_value);
- }
- }
- |
- IF expression '\n' {
- if (ifptr >= ifstmax)
- error("Too many ifs");
- else {
- if (pass2) {
- *++ifptr = *expifp++;
- if (*ifptr != !(yypv[2].ival)) err[pflag]++;
- } else {
- if (expifp >= expifmax)
- error("Too many ifs!");
- *expifp++ = !(yypv[2].ival);
- *++ifptr = !(yypv[2].ival);
- }
- }
- saveopt = fopt;
- fopt = 1;
- list(yypv[2].ival);
- fopt = saveopt;
- }
- |
- ENDIF '\n' {
- if (ifptr == ifstack) err[bflag]++;
- else --ifptr;
- list1();
- }
- |
- label.part END '\n' {
- list(dollarsign);
- peekc = 0;
- }
- |
- label.part END expression '\n' {
- xeq_flag++;
- xeq = $3;
- list($3);
- peekc = 0;
- }
- |
- label.part DEFS expression '\n' {
- if ($3 < 0) err[vflag]++;
- list(dollarsign);
- if ($3) {
- flushbin();
- dollarsign += $3;
- olddollar = dollarsign;
- }
- }
- |
- ARGPSEUDO arg_on ARG arg_off '\n' {
- list1();
- switch ($1->i_value) {
-
- case 0: /* title */
- lineptr = linebuf;
- cp = tempbuf;
- title = titlespace;
- while ((*title++ = *cp++) && (title < &titlespace[TITLELEN]));
- *title = 0;
- title = titlespace;
- break;
-
- case 1: /* rsym */
- if (pass2) break;
- insymtab(tempbuf);
- break;
-
- case 2: /* wsym */
- writesyms = malloc(strlen(tempbuf)+1);
- strcpy(writesyms, tempbuf);
- break;
- case 3: /* include file */
- next_source(tempbuf) ;
- break ;
- }
- }
- |
- ARGPSEUDO arg_on '\n' arg_off {
- fprintf(stderr,"ARGPSEUDO error\n");
- err[fflag]++;
- list(dollarsign);
- }
- |
- LIST '\n' {
- if ($1 != (struct item *) -1) $<ival>2 = 1;
- goto dolopt; }
- |
- LIST expression '\n' {
- dolopt:
- linecnt++;
- if (pass2) {
- lineptr = linebuf;
- switch ($1->i_value) {
- case 0: /* list */
- if ($2 < 0) lstoff = 1;
- if ($2 > 0) lstoff = 0;
- break;
-
- case 1: /* eject */
- if ($2) eject();
- break;
-
- case 2: /* space */
- if ((line + $2) > 60) eject();
- else space($2);
- break;
-
- case 3: /* elist */
- eopt = edef;
- if ($2 < 0) eopt = 0;
- if ($2 > 0) eopt = 1;
- break;
-
- case 4: /* fopt */
- fopt = fdef;
- if ($2 < 0) fopt = 0;
- if ($2 > 0) fopt = 1;
- break;
-
- case 5: /* gopt */
- gopt = gdef;
- if ($2 < 0) gopt = 1;
- if ($2 > 0) gopt = 0;
- break;
-
- case 6: /* mopt */
- mopt = mdef;
- if ($2 < 0) mopt = 0;
- if ($2 > 0) mopt = 1;
- }
- }
- }
- |
- UNDECLARED MACRO parm.list '\n' {
- $1->i_token = MNAME;
- $1->i_value = mfptr;
- mfseek(mfile, (long)mfptr, 0);
- list1();
- mlex() ;
- parm_number = 0;
- }
- |
- OLDMNAME MACRO {
- $1->i_token = MNAME;
- while (yychar != ENDM && yychar) {
- while (yychar != '\n' && yychar)
- yychar = yylex();
- list1();
- yychar = yylex();
- }
- while (yychar != '\n' && yychar) yychar = yylex();
- list1();
- yychar = yylex();
- }
- |
- label.part MNAME al arg.list '\n' {
- expand:
- $2->i_uses++ ;
- arg_flag = 0;
- parm_number = 0;
- list(dollarsign);
- expptr++;
- est = est2;
- est[FLOC] = floc;
- est[TEMPNUM] = (char *)exp_number++;
- floc = (char *)($2->i_value);
- mfseek(mfile, (long)floc, 0);
- }
- ;
-
-
- label.part:
- /*empty*/
- { $$ = NULL; }
- |
- symbol ':' {
- switch($1->i_token) {
- case UNDECLARED:
- if (pass2)
- err[pflag]++;
- else {
- $1->i_token = LABEL;
- $1->i_value = dollarsign;
- }
- break;
- case LABEL:
- if (!pass2) {
- $1->i_token = MULTDEF;
- err[mflag]++;
- } else if ($1->i_value != dollarsign)
- err[pflag]++;
- break;
- default:
- err[mflag]++;
- $1->i_token = MULTDEF;
- }
- }
- ;
-
-
- operation:
- NOOPERAND
- { emit1($1->i_value, 0, 0, 1); }
- |
- JP expression
- { emit(3, 0303, $2, $2 >> 8); }
- |
- CALL expression
- { emit(3, 0315, $2, $2 >> 8); }
- |
- RST expression
- { if ($2 > 7 || $2 < 0)
- err[vflag]++;
- emit(1, $1->i_value + (($2 & 7) << 3));
- }
- |
- ADD ACC ',' expression
- { emit1(0306, 0, $4, 3); }
- |
- ARITHC ACC ',' expression
- { emit1(0306 + ($1->i_value << 3), 0, $4, 3); }
- |
- LOGICAL expression
- { emit1(0306 | ($1->i_value << 3), 0, $2, 3); }
- |
- LOGICAL ACC ',' expression /* -cdk */
- { emit1(0306 | ($1->i_value << 3), 0, $4, 3); }
- |
- ADD ACC ',' reg
- { emit1(0200 + ($4 & 0377), $4, 0, 0); }
- |
- ARITHC ACC ',' reg
- { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); }
- |
- LOGICAL reg
- { emit1(0200 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); }
- |
- LOGICAL ACC ',' reg /* -cdk */
- { emit1(0200 + ($1->i_value << 3) + ($4 & 0377), $4, 0, 0); }
- |
- SHIFT reg
- { emit1(0145400 + ($1->i_value << 3) + ($2 & 0377), $2, 0, 0); }
- |
- INCDEC reg
- { emit1($1->i_value + (($2 & 0377) << 3) + 4, $2, 0, 0); }
- |
- ARITHC HL ',' bcdehlsp
- { if ($1->i_value == 1)
- emit(2,0355,0112+$4);
- else
- emit(2,0355,0102+$4);
- }
- |
- ADD mar ',' bcdesp
- { emitdad($2,$4); }
- |
- ADD mar ',' mar
- {
- if ($2 != $4) {
- fprintf(stderr,"ADD mar, mar error\n");
- err[fflag]++;
- }
- emitdad($2,$4);
- }
- |
- INCDEC evenreg
- { emit1(($1->i_value << 3) + ($2 & 0377) + 3, $2, 0, 1); }
- |
- PUSHPOP pushable
- { emit1($1->i_value + ($2 & 0377), $2, 0, 1); }
- |
- BIT expression ',' reg
- {
- if ($2 < 0 || $2 > 7)
- err[vflag]++;
- emit1($1->i_value + (($2 & 7) << 3) + ($4 & 0377), $4, 0, 0);
- }
- |
- JP condition ',' expression
- { emit(3, 0302 + $2, $4, $4 >> 8); }
- |
- JP '(' mar ')'
- { emit1(0351, $3, 0, 1); }
- |
- CALL condition ',' expression
- { emit(3, 0304 + $2, $4, $4 >> 8); }
- |
- JR expression
- { emitjr(030,$2); }
- |
- JR spcondition ',' expression
- { emitjr($1->i_value + $2, $4); }
- |
- DJNZ expression
- { emitjr($1->i_value, $2); }
- |
- RET
- { emit(1, $1->i_value); }
- |
- RET condition
- { emit(1, 0300 + $2); }
- |
- LD reg ',' reg
- {
- if (($2 & 0377) == 6 && ($4 & 0377) == 6) {
- fprintf(stderr,"LD reg, reg error\n");
- err[fflag]++;
- }
- emit1(0100 + (($2 & 7) << 3) + ($4 & 7),$2 | $4, 0, 0);
- }
- |
- LD reg ',' expression
- { emit1(6 + (($2 & 0377) << 3), $2, $4, 2); }
- |
- LD reg ',' '(' RP ')'
- { if ($2 != 7) {
- fprintf(stderr,"LD reg, (RP) error\n");
- err[fflag]++;
- }
- else emit(1, 012 + $5->i_value);
- }
- |
- LD reg ',' parenexpr
- {
- if ($2 != 7) {
- fprintf(stderr,"LD reg, (expr) error\n");
- err[fflag]++;
- }
- else emit(3, 072, $4, $4 >> 8);
- }
- |
- LD '(' RP ')' ',' ACC
- { emit(1, 2 + $3->i_value); }
- |
- LD parenexpr ',' ACC
- { emit(3, 062, $2, $2 >> 8); }
- |
- LD reg ',' MISCREG
- {
- if ($2 != 7) {
- fprintf(stderr,"LD reg, MISCREG error\n");
- err[fflag]++;
- }
- else emit(2, 0355, 0127 + $4->i_value);
- }
- |
- LD MISCREG ',' ACC
- { emit(2, 0355, 0107 + $2->i_value); }
- |
- LD evenreg ',' lxexpression
- { emit1(1 + ($2 & 060), $2, $4, 5); }
- |
- LD evenreg ',' parenexpr
- {
- if (($2 & 060) == 040)
- emit1(052, $2, $4, 5);
- else
- emit(4, 0355, 0113 + $2, $4, $4 >> 8);
- }
- |
- LD parenexpr ',' evenreg
- {
- if (($4 & 060) == 040)
- emit1(042, $4, $2, 5);
- else
- emit(4, 0355, 0103 + $4, $2, $2 >> 8);
- }
- |
- LD evenreg ',' mar
- {
- if ($2 != 060) {
- fprintf(stderr,"LD evenreg error\n");
- err[fflag]++;
- }
- else
- emit1(0371, $4, 0, 1);
- }
- |
- EX RP ',' HL
- {
- if ($2->i_value != 020) {
- fprintf(stderr,"EX RP, HL error\n");
- err[fflag]++;
- }
- else
- emit(1, 0353);
- }
- |
- EX AF ',' AF setqf '\'' clrqf
- { emit(1, 010); }
- |
- EX '(' SP ')' ',' mar
- { emit1(0343, $6, 0, 1); }
- |
- IN realreg ',' parenexpr
- {
- if ($2 != 7) {
- fprintf(stderr,"IN reg, (expr) error\n");
- err[fflag]++;
- }
- else {
- if ($4 < 0 || $4 > 255)
- err[vflag]++;
- emit(2, $1->i_value, $4);
- }
- }
- |
- IN realreg ',' '(' C ')'
- { emit(2, 0355, 0100 + ($2 << 3)); }
- |
- IN F ',' '(' C ')'
- { emit(2, 0355, 0160); }
- |
- OUT parenexpr ',' ACC
- {
- if ($2 < 0 || $2 > 255)
- err[vflag]++;
- emit(2, $1->i_value, $2);
- }
- |
- OUT '(' C ')' ',' realreg
- { emit(2, 0355, 0101 + ($6 << 3)); }
- |
- IM expression
- {
- if ($2 > 2 || $2 < 0)
- err[vflag]++;
- else
- emit(2, $1->i_value >> 8, $1->i_value + (($2 + ($2 > 0)) << 3));
- }
- |
- PHASE expression
- {
- if (phaseflag) {
- err[oflag]++;
- } else {
- phaseflag = 1;
- phdollar = dollarsign;
- dollarsign = $2;
- phbegin = dollarsign;
- }
- }
- |
- DEPHASE
- {
- if (!phaseflag) {
- err[oflag]++;
- } else {
- phaseflag = 0;
- dollarsign = phdollar + dollarsign - phbegin;
- }
- }
- |
- ORG expression
- {
- if (phaseflag) {
- err[oflag]++;
- dollarsign = phdollar + dollarsign - phbegin;
- phaseflag = 0;
- }
- if ($2-dollarsign) {
- flushbin();
- olddollar = $2;
- dollarsign = $2;
- }
- }
- |
- DEFB db.list
- |
- DEFW dw.list
- |
- ENDM
- ;
-
-
- parm.list:
- |
- parm.element
- |
- parm.list ',' parm.element
- ;
-
-
- parm.element:
- UNDECLARED
- {
- $1->i_token = MPARM;
- if (parm_number >= PARMMAX)
- error("Too many parameters");
- $1->i_value = parm_number++;
- }
- ;
-
-
- arg.list:
- /* empty */
- |
- arg.element
- |
- arg.list ',' arg.element
- ;
-
-
- arg.element:
- ARG
- {
- cp = malloc(strlen(tempbuf)+1);
- est2[parm_number++] = cp;
- strcpy(cp, tempbuf);
- }
- ;
- reg:
- realreg
- |
- mem
- ;
- realreg:
- REGNAME
- {
- $$ = $1->i_value;
- }
- |
- ACC
- {
- $$ = $1->i_value;
- }
- |
- C
- {
- $$ = $1->i_value;
- }
- ;
- mem:
- '(' HL ')'
- {
- $$ = 6;
- }
- |
- '(' INDEX expression ')'
- {
- disp = $3;
- $$ = ($2->i_value & 0177400) | 6;
- }
- |
- '(' INDEX ')'
- {
- disp = 0;
- $$ = ($2->i_value & 0177400) | 6;
- }
- ;
- evenreg:
- bcdesp
- |
- mar
- ;
- pushable:
- RP
- {
- $$ = $1->i_value;
- }
- |
- AF
- {
- $$ = $1->i_value;
- }
- |
- mar
- ;
- bcdesp:
- RP
- {
- $$ = $1->i_value;
- }
- |
- SP
- {
- $$ = $1->i_value;
- }
- ;
- bcdehlsp:
- bcdesp
- |
- HL
- {
- $$ = $1->i_value;
- }
- ;
- mar:
- HL
- {
- $$ = $1->i_value;
- }
- |
- INDEX
- {
- $$ = $1->i_value;
- }
- ;
- condition:
- spcondition
- |
- COND
- {
- $$ = $1->i_value;
- }
- ;
- spcondition:
- SPCOND
- {
- $$ = $1->i_value;
- }
- |
- C
- { $$ = 030; }
- ;
- db.list:
- db.list.element
- |
- db.list ',' db.list.element
- ;
- db.list.element:
- TWOCHAR
- {
- emit(2, $1, $1>>8);
- }
- |
- STRING
- {
- cp = $1;
- while (*cp != '\0')
- emit(1,*cp++);
- }
- |
- expression
- {
- if ($1 < -128 || $1 > 255)
- err[vflag]++;
- emit(1, $1 & 0377);
- }
- ;
-
-
- dw.list:
- dw.list.element
- |
- dw.list ',' dw.list.element
- ;
-
-
- dw.list.element:
- expression
- {
- emit(2, $1, $1>>8);
- }
- ;
-
-
-
- lxexpression:
- expression
- |
- TWOCHAR
- ;
-
- parenexpr:
- '(' expression ')'
- { $$ = $2; }
- ;
-
- expression:
- error
- {
- err[eflag]++;
- $$ = 0;
- }
- |
- LABEL
- { $$ = $1->i_value; $1->i_uses++ ; }
- |
- NUMBER
- |
- ONECHAR
- |
- EQUATED
- { $$ = $1->i_value; }
- |
- WASEQUATED
- { $$ = $1->i_value; }
- |
- DEFLED
- { $$ = $1->i_value; }
- |
- '$'
- { $$ = dollarsign; }
- |
- UNDECLARED
- {
- err[uflag]++;
- $$ = 0;
- }
- |
- MULTDEF
- { $$ = $1->i_value; }
- |
- expression '+' expression
- { $$ = $1 + $3; }
- |
- expression '-' expression
- { $$ = $1 - $3; }
- |
- expression '/' expression
- { $$ = $1 / $3; }
- |
- expression '*' expression
- { $$ = $1 * $3; }
- |
- expression MOD expression
- { $$ = $1 % $3; }
- |
- expression '&' expression
- { $$ = $1 & $3; }
- |
- expression '|' expression
- { $$ = $1 | $3; }
- |
- expression '^' expression
- { $$ = $1 ^ $3; }
- |
- expression SHL expression
- { $$ = $1 << $3; }
- |
- expression SHR expression
- { $$ = (($1 >> 1) & 077777) >> ($3 - 1); }
- |
- '[' expression ']'
- { $$ = $2; }
- |
- NOT expression
- { $$ = ~$2; }
- |
- '+' expression %prec UNARY
- { $$ = $2; }
- |
- '-' expression %prec UNARY
- { $$ = -$2; }
- ;
-
- symbol:
- UNDECLARED
- |
- LABEL
- |
- MULTDEF
- |
- EQUATED
- |
- WASEQUATED
- |
- DEFLED
- ;
-
-
- al:
- {
- if (expptr >= MAXEXP)
- error("Macro expansion level");
- est2 = (char **) malloc((PARMMAX +4) * sizeof(char *));
- expstack[expptr] = (char *)est2 ;
- for (i=0; i<PARMMAX; i++)
- est2[i] = 0;
- arg_flag++;
- }
- ;
-
-
- arg_on:
- { arg_flag++; }
- ;
-
- arg_off:
- { arg_flag = 0; }
- ;
-
- setqf:
- { quoteflag++; }
- ;
-
- clrqf:
- { quoteflag = 0; }
-
- ;
-
- %%
- /*extern int yylval;*/
-
- #define F_END 0
- #define OTHER 1
- #define SPACE 2
- #define DIGIT 3
- #define LETTER 4
- #define STARTER 5
-
-
- /*
- * This is the table of character classes. It is used by the lexical
- * analyser. (yylex())
- */
- char charclass[] = {
- F_END, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
- OTHER, SPACE, OTHER, OTHER, OTHER, SPACE, OTHER, OTHER,
- OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
- OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
- SPACE, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
- OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER, OTHER,
- DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
- DIGIT, DIGIT, OTHER, OTHER, OTHER, OTHER, OTHER, STARTER,
- STARTER,LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, OTHER, OTHER, OTHER, OTHER, LETTER,
- OTHER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, OTHER, OTHER, OTHER, OTHER, OTHER,
- };
-
-
- /*
- * the following table tells which characters are parts of numbers.
- * The entry is non-zero for characters which can be parts of numbers.
- */
- char numpart[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', 0, 0, 0, 0, 0, 0,
- 0, 'A', 'B', 'C', 'D', 'E', 'F', 0,
- 'H', 0, 0, 0, 0, 0, 0, 'O',
- 0, 'Q', 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 'a', 'b', 'c', 'd', 'e', 'f', 0,
- 'h', 0, 0, 0, 0, 0, 0, 'o',
- 0, 'q', 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0};
-
-
-
-
- /*
- * the following table is a list of assembler mnemonics;
- * for each mnemonic the associated machine-code bit pattern
- * and symbol type are given.
- */
- struct item keytab[] = {
- "a", 7, ACC, 0,
- "adc", 1, ARITHC, 0,
- "add", 0, ADD, 0,
- "af", 060, AF, 0,
- "and", 4, LOGICAL, 0,
- "ascii",0, DEFB, 0,
- "b", 0, REGNAME, 0,
- "bc", 0, RP, 0,
- "bit", 0145500,BIT, 0,
- "block",0, DEFS, 0,
- "byte", 0, DEFB, 0,
- "c", 1, C, 0,
- "call", 0315, CALL, 0,
- "ccf", 077, NOOPERAND, 0,
- "cmp", 7, LOGICAL, 0, /* -cdk */
- "cp", 7, LOGICAL, 0,
- "cpd", 0166651,NOOPERAND, 0,
- "cpdr", 0166671,NOOPERAND, 0,
- "cpi", 0166641,NOOPERAND, 0,
- "cpir", 0166661,NOOPERAND, 0,
- "cpl", 057, NOOPERAND, 0,
- "d", 2, REGNAME, 0,
- "daa", 0047, NOOPERAND, 0,
- "de", 020, RP, 0,
- "dec", 1, INCDEC, 0,
- "defb", 0, DEFB, 0,
- "defl",0, DEFL, 0,
- "defs", 0, DEFS, 0,
- "defw", 0, DEFW, 0,
- "dephase", 0, DEPHASE, 0,
- "di", 0363, NOOPERAND, 0,
- "djnz", 020, DJNZ, 0,
- "e", 3, REGNAME, 0,
- "ei", 0373, NOOPERAND, 0,
- "eject",1, LIST, 0,
- "elist",3, LIST, 0,
- "end", 0, END, 0,
- "endif",0, ENDIF, 0,
- "endm", 0, ENDM, 0,
- "equ", 0, EQU, 0,
- "ex", 0, EX, 0,
- "exx", 0331, NOOPERAND, 0,
- "f", 0, F, 0,
- "flist",4, LIST, 0,
- "glist",5, LIST, 0,
- "h", 4, REGNAME, 0,
- "halt", 0166, NOOPERAND, 0,
- "hl", 040, HL, 0,
- "i", 0, MISCREG, 0,
- "if", 0, IF, 0,
- "im", 0166506,IM, 0,
- "in", 0333, IN, 0,
- "inc", 0, INCDEC, 0,
- "include", 3, ARGPSEUDO, 0,
- "ind", 0166652,NOOPERAND, 0,
- "indr", 0166672,NOOPERAND, 0,
- "ini", 0166642,NOOPERAND, 0,
- "inir", 0166662,NOOPERAND, 0,
- "ix", 0156440,INDEX, 0,
- "iy", 0176440,INDEX, 0,
- "jmp", 0303, JP, 0, /* -cdk */
- "jp", 0303, JP, 0,
- "jr", 040, JR, 0,
- "l", 5, REGNAME, 0,
- "ld", 0, LD, 0,
- "ldd", 0166650,NOOPERAND, 0,
- "lddr", 0166670,NOOPERAND, 0,
- "ldi", 0166640,NOOPERAND, 0,
- "ldir", 0166660,NOOPERAND, 0,
- "list", 0, LIST, 0,
- "m", 070, COND, 0,
- "macro",0, MACRO, 0,
- "max", 1, MINMAX, 0,
- "min", 0, MINMAX, 0,
- "mlist",6, LIST, 0,
- "mod", 0, MOD, 0,
- "nc", 020, SPCOND, 0,
- "neg", 0166504,NOOPERAND, 0,
- "nolist",-1, LIST, 0,
- "nop", 0, NOOPERAND, 0,
- "not", 0, NOT, 0,
- "nv", 040, COND, 0,
- "nz", 0, SPCOND, 0,
- "or", 6, LOGICAL, 0,
- "org", 0, ORG, 0,
- "otdr",0166673,NOOPERAND, 0,
- "otir",0166663,NOOPERAND, 0,
- "out", 0323, OUT, 0,
- "outd", 0166653,NOOPERAND, 0,
- "outi", 0166643,NOOPERAND, 0,
- "p", 060, COND, 0,
- "pe", 050, COND, 0,
- "phase", 0, PHASE, 0,
- "po", 040, COND, 0,
- "pop", 0301, PUSHPOP, 0,
- "push", 0305, PUSHPOP, 0,
- "r", 010, MISCREG, 0,
- "res", 0145600,BIT, 0,
- "ret", 0311, RET, 0,
- "reti", 0166515,NOOPERAND, 0,
- "retn", 0166505,NOOPERAND, 0,
- "rl", 2, SHIFT, 0,
- "rla", 027, NOOPERAND, 0,
- "rlc", 0, SHIFT, 0,
- "rlca", 07, NOOPERAND, 0,
- "rld", 0166557,NOOPERAND, 0,
- "rr", 3, SHIFT, 0,
- "rra", 037, NOOPERAND, 0,
- "rrc", 1, SHIFT, 0,
- "rrca", 017, NOOPERAND, 0,
- "rrd", 0166547,NOOPERAND, 0,
- "rst", 0307, RST, 0,
- "rsym", 1, ARGPSEUDO, 0,
- "sbc", 3, ARITHC, 0,
- "scf", 067, NOOPERAND, 0,
- "set", 0145700,BIT, 0,
- "shl", 0, SHL, 0,
- "shr", 0, SHR, 0,
- "sla", 4, SHIFT, 0,
- "sp", 060, SP, 0,
- "space",2, LIST, 0,
- "sra", 5, SHIFT, 0,
- "srl", 7, SHIFT, 0,
- "sub", 2, LOGICAL, 0,
- "title",0, ARGPSEUDO, 0,
- "v", 050, COND, 0,
- "word", 0, DEFW, 0,
- "wsym", 2, ARGPSEUDO, 0,
- "xor", 5, LOGICAL, 0,
- "z", 010, SPCOND, 0,
- };
-
- /*
- * user-defined items are tabulated in the following table.
- */
-
- struct item itemtab[ITEMTABLESIZE];
- struct item *itemmax = &itemtab[ITEMTABLESIZE];
-
-
-
-
-
- /*
- * lexical analyser, called by yyparse.
- */
- yylex()
- {
- register char c;
- register char *p;
- register int radix;
- int limit;
-
- if (arg_flag)
- return(getarg());
- loop switch(charclass[c = nextchar()]) {
- case F_END:
- if (expptr) {
- popsi();
- continue;
- } else return(0);
-
- case SPACE:
- break;
- case LETTER:
- case STARTER:
- p = tempbuf;
- do {
- if (p >= tempmax)
- error(symlong);
- *p++ = (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
- while ((c = nextchar()) == '$')
- ;
- } while (charclass[c]==LETTER || charclass[c]==DIGIT);
- if (p - tempbuf > MAXSYMBOLSIZE)
- p = tempbuf + MAXSYMBOLSIZE;
- *p++ = '\0';
- peekc = c;
- return(tokenofitem(UNDECLARED));
- case DIGIT:
- if (*ifptr) return(skipline(c));
- p = tempbuf;
- do {
- if (p >= tempmax)
- error(symlong);
- *p++ = (c >= 'A' && c <= 'Z') ? c + 'a' - 'A' : c;
- while ((c = nextchar()) == '$');
- }
- while(numpart[c]);
- peekc = c;
- *p-- = '\0';
- switch(*p) {
- case 'o':
- case 'q':
- radix = 8;
- limit = 020000;
- *p = '\0';
- break;
- case 'd':
- radix = 10;
- limit = 3276;
- *p = '\0';
- break;
- case 'h':
- radix = 16;
- limit = 010000;
- *p = '\0';
- break;
- case 'b':
- radix = 2;
- limit = 077777;
- *p = '\0';
- break;
- default:
- radix = 10;
- limit = 3276;
- p++;
- break;
- }
-
- /*
- * tempbuf now points to the number, null terminated
- * with radix 'radix'.
- */
- yylval.ival = 0;
- p = tempbuf;
- do {
- c = *p - (*p > '9' ? ('a' - 10) : '0');
- if (c >= radix)
- {
- err[iflag]++;
- yylval.ival = 0;
- break;
- }
- if (yylval.ival < limit ||
- (radix == 10 && yylval.ival == 3276 && c < 8) ||
- (radix == 2 && yylval.ival == limit))
- yylval.ival = yylval.ival * radix + c;
- else {
- err[vflag]++;
- yylval.ival = 0;
- break;
- }
- }
- while(*++p != '\0');
- return(NUMBER);
- default:
- if (*ifptr)
- return(skipline(c));
- switch(c) {
- case ';':
- return(skipline(c));
- case '\'':
- if (quoteflag) return('\'');
- p = tempbuf;
- p[1] = 0;
- do switch(c = nextchar()) {
- case '\0':
- case '\n':
- err[bflag]++;
- goto retstring;
- case '\'':
- if ((c = nextchar()) != '\'') {
- retstring:
- peekc = c;
- *p = '\0';
- if ((p-tempbuf) >2) {
- yylval.cval = tempbuf;
- return(STRING);
- } else if (p-tempbuf == 2) {
- p = tempbuf;
- yylval.ival = *p++ ;
- yylval.ival |= *p<<8;
- return(TWOCHAR);
- } else {
- p = tempbuf;
- yylval.ival = *p++;
- return(ONECHAR);
- }
- }
- default:
- *p++ = c;
- } while (p < tempmax);
- /*
- * if we break out here, our string is longer than
- * our input line
- */
- error("string buffer overflow");
- default:
- return(c);
- }
- }
- }
-
- /*
- * return the token associated with the string pointed to by
- * tempbuf. if no token is associated with the string, associate
- * deftoken with the string and return deftoken.
- * in either case, cause yylval to point to the relevant
- * symbol table entry.
- */
-
- tokenofitem(deftoken)
- int deftoken;
- {
- register char *p;
- register struct item * ip;
- register i;
- int r, l, u, hash;
-
-
- #ifdef T_DEBUG
- fputs("'tokenofitem entry' ", stderr) ;
- fputs(tempbuf, stderr) ;
- #endif
- /*
- * binary search
- */
- l = 0;
- u = (sizeof keytab/sizeof keytab[0])-1;
- while (l <= u) {
- i = (l+u)/2;
- ip = &keytab[i];
- if ((r = strcmp(tempbuf, ip->i_string)) == 0)
- goto found;
- if (r < 0)
- u = i-1;
- else
- l = i+1;
- }
-
- /*
- * hash into item table
- */
- hash = 0;
- p = tempbuf;
- while (*p) hash += *p++;
- hash %= ITEMTABLESIZE;
- ip = &itemtab[hash];
-
- loop {
- if (ip->i_token == 0)
- break;
- if (strcmp(tempbuf, ip->i_string) == 0)
- goto found;
- if (++ip >= itemmax)
- ip = itemtab;
- }
-
- if (!deftoken) {
- i = 0 ;
- goto token_done ;
- }
- if (++nitems > ITEMTABLESIZE-20)
- error("item table overflow");
- ip->i_string = malloc(strlen(tempbuf)+1);
- ip->i_token = deftoken;
- ip->i_uses = 0 ;
- strcpy(ip->i_string, tempbuf);
-
- found:
- if (*ifptr) {
- if (ip->i_token == ENDIF) {
- i = ENDIF ;
- goto token_done ;
- }
- if (ip->i_token == IF) {
- if (ifptr >= ifstmax)
- error("Too many ifs");
- else *++ifptr = 1;
- }
- i = skipline(' ');
- goto token_done ;
- }
- yylval.itemptr = ip;
- i = ip->i_token;
- token_done:
- #ifdef T_DEBUG
- fputs("\t'tokenofitem exit'\n", stderr) ;
- #endif
- return(i) ;
- }
-
-
- /*
- * interchange two entries in the item table -- used by qsort
- */
- interchange(i, j)
- {
- register struct item *fp, *tp;
- struct item temp;
-
- fp = &itemtab[i];
- tp = &itemtab[j];
- temp.i_string = fp->i_string;
- temp.i_value = fp->i_value;
- temp.i_token = fp->i_token;
- temp.i_uses = fp->i_uses;
-
- fp->i_string = tp->i_string;
- fp->i_value = tp->i_value;
- fp->i_token = tp->i_token;
- fp->i_uses = tp->i_uses;
-
- tp->i_string = temp.i_string;
- tp->i_value = temp.i_value;
- tp->i_token = temp.i_token;
- tp->i_uses = temp.i_uses;
- }
-
-
-
- /*
- * quick sort -- used by putsymtab to sort the symbol table
- */
- qsort(m, n)
- {
- register i, j;
-
- if (m < n) {
- i = m;
- j = n+1;
- loop {
- do i++; while(strcmp(itemtab[i].i_string,
- itemtab[m].i_string) < 0);
- do j--; while(strcmp(itemtab[j].i_string,
- itemtab[m].i_string) > 0);
- if (i < j) interchange(i, j); else break;
- }
- interchange(m, j);
- qsort(m, j-1);
- qsort(j+1, n);
- }
- }
-
-
-
- /*
- * get the next character
- */
- nextchar()
- {
- register int c, ch;
- static char *earg;
- char *getlocal();
-
- if (peekc != -1) {
- c = peekc;
- peekc = -1;
- return(c);
- }
-
- start:
- if (earg) {
- if (*earg)
- return(addtoline(*earg++));
- earg = 0;
- }
-
- if (expptr) {
- if ((ch = getm()) == '\1') { /* expand argument */
- ch = getm() - 'A';
- if (ch >= 0 && ch < PARMMAX && est[ch])
- earg = est[ch];
- goto start;
- }
- if (ch == '\2') { /* local symbol */
- ch = getm() - 'A';
- if (ch >= 0 && ch < PARMMAX && est[ch]) {
- earg = est[ch];
- goto start;
- }
- earg = getlocal(ch, (int)est[TEMPNUM]);
- goto start;
- }
-
- return(addtoline(ch));
- }
- ch = getc(now_file) ;
- /* if EOF, check for include file */
- if (ch == EOF) {
- while (ch == EOF && now_in) {
- fclose(fin[now_in]) ;
- free(src_name[now_in]) ;
- now_file = fin[--now_in] ;
- ch = getc(now_file) ;
- }
- if (linein[now_in] < 0) {
- lstoff = 1 ;
- linein[now_in] = -linein[now_in] ;
- } else {
- lstoff = 0 ;
- }
- if (pass2 && iflist()) {
- lineout() ;
- fprintf(fout, "**** %s ****\n", src_name[now_in]) ;
- }
- }
- if (ch == '\n')
- linein[now_in]++ ;
-
- return(addtoline(ch)) ;
- }
-
-
- /*
- * skip to rest of the line -- comments and if skipped lines
- */
- skipline(ac)
- {
- register c;
-
- c = ac;
- while (c != '\n' && c != '\0')
- c = nextchar();
- return('\n');
- }
-
-
-
- main(argc, argv)
- char **argv;
- {
- register struct item *ip;
- register i;
- int files;
- #ifdef DBUG
- extern yydebug;
- #endif
-
- fout = stdout ;
- fin[0] = stdin ;
- now_file = stdin ;
- files = 0;
-
- for (i=1; i<argc; i++) {
- if (*argv[i] == '-') while (*++argv[i]) switch(*argv[i]) {
-
- case 'b': /* no binary */
- bopt = 0;
- continue;
-
- #ifdef DBUG
- case 'd': /* debug */
- yydebug++;
- continue;
- #endif
-
- case 'e': /* error list only */
- eopt = 0;
- edef = 0;
- continue;
-
- case 'f': /* print if skipped lines */
- fopt++;
- fdef++;
- continue;
-
- case 'g': /* do not list extra code */
- gopt = 0;
- gdef = 0;
- continue;
-
- case 'i': /* do not list include files */
- iopt = 1 ;
- continue ;
-
- case 'l': /* no list */
- lopt++;
- continue;
-
- case 'L': /* force listing of everything */
- lston++;
- continue;
-
- case 'm': /* print macro expansions */
- mdef++;
- mopt++;
- continue;
-
- case 'n': /* put line numbers off */
- nopt-- ;
- continue;
-
- case 'o': /* list to standard output */
- oopt++;
- continue;
-
- case 'p': /* put out four \n's for eject */
- popt-- ;
- continue;
-
- case 's': /* don't produce a symbol list */
- sopt++;
- continue;
-
- case 't':
- topt = 0;
- continue;
-
- default: /* error */
- error("Unknown option");
-
- } else if (files++ == 0) {
- sourcef = argv[i];
- strcpy(src, sourcef);
- suffix(src,".z");
- if ((now_file = fopen(src, "r")) == NULL)
- error("Cannot open source file");
- now_in = 0 ;
- fin[now_in] = now_file ;
- src_name[now_in] = src ;
- } else if (files)
- error("Too many arguments");
- }
-
-
- if (files == 0)
- error("No source file");
- strcpy(bin, sourcef);
- suffix(bin,".hex");
- if (bopt)
- #ifdef MSDOS
- if (( fbuf = fopen(bin, "wb")) == NULL)
- #else
- if (( fbuf = fopen(bin, "w")) == NULL)
- #endif
- error("Cannot create binary file");
- if (!lopt && !oopt) {
- strcpy(listf, sourcef);
- suffix(listf,".lst");
- if ((fout = fopen(listf, "w")) == NULL)
- error("Cannot create list file");
- } else
- fout = stdout ;
- strcpy(mtmp, sourcef);
- suffix(mtmp,".tmp");
- #ifdef MSDOS
- mfile = mfopen(mtmp,"w+b") ;
- #else
- mfile = mfopen(mtmp,"w+") ;
- #endif
- if (mfile == NULL) {
- error("Cannot create temp file");
- }
- /*unlink(mtmp);*/
-
- /*
- * get the time
- */
- time(&now);
- timp = ctime(&now);
- timp[16] = 0;
- timp[24] = 0;
-
- title = sourcef;
- /*
- * pass 1
- */
- #ifdef DEBUG
- fputs("DEBUG-pass 1\n", stderr) ;
- #endif
- setvars();
- yyparse();
- pass2++;
- ip = &itemtab[-1];
- while (++ip < itemmax) {
- /* reset use count */
- ip->i_uses = 0 ;
-
- /* set macro names, equated and defined names */
- switch (ip->i_token) {
- case MNAME:
- ip->i_token = OLDMNAME;
- break;
-
- case EQUATED:
- ip->i_token = WASEQUATED;
- break;
-
- case DEFLED:
- ip->i_token = UNDECLARED;
- break;
- }
- }
- setvars();
- fseek(now_file, (long)0, 0);
-
- #ifdef DEBUG
- fputs("DEBUG- pass 2\n", stderr) ;
- #endif
- yyparse();
-
-
- if (bopt) {
- flushbin();
- putc(':', fbuf);
- if (xeq_flag) {
- puthex(0, fbuf);
- puthex(xeq >> 8, fbuf);
- puthex(xeq, fbuf);
- puthex(1, fbuf);
- puthex(255-(xeq >> 8)-xeq, fbuf);
- } else
- for (i = 0; i < 10; i++)
- putc('0', fbuf);
- putc('\n', fbuf);
- fflush(fbuf);
- }
-
- if (!lopt)
- fflush(fout);
- if (writesyms)
- outsymtab(writesyms);
- if (eopt)
- erreport();
- if (!lopt && !sopt)
- putsymtab();
- if (!lopt) {
- eject();
- fflush(fout);
- }
- exit(0);
- }
-
-
- /*
- * set some data values before each pass
- */
- setvars()
- {
- register i;
-
- peekc = -1;
- linein[now_in] = linecnt = 0;
- exp_number = 0;
- emitptr = emitbuf;
- lineptr = linebuf;
- ifptr = ifstack;
- expifp = expif;
- *ifptr = 0;
- dollarsign = 0;
- olddollar = 0;
- phaseflag = 0;
- for (i=0; i<FLAGS; i++) err[i] = 0;
- }
-
-
-
- /*
- * print out an error message and die
- */
- error(as)
- char *as;
- {
-
- *linemax = 0;
- fprintf(fout, "%s\n", linebuf);
- fflush(fout);
- fprintf(stderr, "%s\n", as) ;
- exit(1);
- }
-
-
-
- /*
- * output the symbol table
- */
- putsymtab()
- {
- register struct item *tp, *fp;
- int i, j, k, t, rows;
- char c, c1 ;
-
- if (!nitems)
- return;
-
- /* compact the table so unused and UNDECLARED entries are removed */
- tp = &itemtab[-1];
- for (fp = itemtab; fp<itemmax; fp++) {
- if (fp->i_token == UNDECLARED) {
- nitems--;
- continue;
- }
- if (fp->i_token == 0)
- continue;
- tp++;
- if (tp != fp) {
- tp->i_string = fp->i_string;
- tp->i_value = fp->i_value;
- tp->i_token = fp->i_token;
- tp->i_uses = fp->i_uses ;
- }
- }
-
- tp++;
- tp->i_string = "{";
-
- /* sort the table */
- qsort(0, nitems-1);
-
- title = "** Symbol Table **";
-
- rows = (nitems+3) / 4;
- if (rows+5+line > 60)
- eject();
- lineout();
- fprintf(fout,"\n\n\nSymbol Table:\n\n") ;
- line += 4;
-
- for (i=0; i<rows; i++) {
- for(j=0; j<4; j++) {
- k = rows*j+i;
- if (k < nitems) {
- tp = &itemtab[k];
- t = tp->i_token;
- c = ' ' ;
- if (t == EQUATED || t == DEFLED)
- c = '=' ;
- if (tp->i_uses == 0)
- c1 = '+' ;
- else
- c1 = ' ' ;
- fprintf(fout, "%-15s%c%4x%c ",
- tp->i_string, c, tp->i_value & 0xffff, c1);
- }
- }
- lineout();
- putc('\n', fout);
- }
- }
-
-
-
-
- /*
- * put out error report
- */
- erreport()
- {
- register i, numerr;
-
- if (line > 50) eject();
- lineout();
- numerr = 0;
- for (i=0; i<FLAGS; i++) numerr += keeperr[i];
- if (numerr) {
- fputs("\n\n\nError report:\n\n", fout);
- fprintf(fout, "%6d errors\n", numerr);
- line += 5;
- } else {
- fputs("\n\n\nStatistics:\n", fout);
- line += 3;
- }
-
- for (i=0; i<FLAGS; i++)
- if (keeperr[i]) {
- lineout();
- fprintf(fout, "%6d %c -- %s error\n",
- keeperr[i], errlet[i], errname[i]);
- }
-
- if (line > 55) eject();
- lineout();
- fprintf(fout, "\n%6d\tsymbols\n", nitems);
- fprintf(fout, "%6d\tbytes\n", nbytes);
- line += 2;
- if (mfptr) {
- if (line > 53) eject();
- lineout();
- fprintf(fout, "\n%6d\tmacro calls\n", exp_number);
- fprintf(fout, "%6d\tmacro bytes\n", mfptr);
- fprintf(fout, "%6d\tinvented symbols\n", invented/2);
- line += 3;
- }
- }
-
-
- /*
- * lexical analyser for macro definition
- */
- mlex()
- {
- register char *p;
- register c;
- int t;
-
- /*
- * move text onto macro file, changing formal parameters
- */
- #ifdef M_DEBUG
- fprintf(stderr,"enter 'mlex'\t") ;
- #endif
- inmlex++;
-
- c = nextchar();
- loop {
- switch(charclass[c]) {
-
- case DIGIT:
- while (numpart[c]) {
- putm(c);
- c = nextchar();
- }
- continue;
-
- case STARTER:
- case LETTER:
- t = 0;
- p = tempbuf+MAXSYMBOLSIZE+2;
- do {
- if (p >= tempmax)
- error(symlong);
- *p++ = c;
- if (t < MAXSYMBOLSIZE)
- tempbuf[t++] = (c >= 'A' && c <= 'Z') ?
- c+'a'-'A' : c;
- c = nextchar();
- } while (charclass[c]==LETTER || charclass[c]==DIGIT);
-
- tempbuf[t] = 0;
- *p++ = '\0';
- p = tempbuf+MAXSYMBOLSIZE+2;
- t = tokenofitem(0);
- if (t != MPARM) while (*p) putm(*p++);
- else {
- if (*(yylval.itemptr->i_string) == '?') putm('\2');
- else putm('\1');
- putm(yylval.itemptr->i_value + 'A');
- }
- if (t == ENDM) goto done;
- continue;
-
- case F_END:
- if (expptr) {
- popsi();
- c = nextchar();
- continue;
- }
-
- goto done;
-
- default:
- if (c == '\n') {
- linecnt++;
- }
- if (c != '\1') putm(c);
- c = nextchar();
- }
- }
-
- /*
- * finish off the file entry
- */
- done:
- while(c != EOF && c != '\n' && c != '\0') c = nextchar();
- linecnt++;
- putm('\n');
- putm('\n');
- putm(0);
-
- for (c=0; c<ITEMTABLESIZE; c++)
- if (itemtab[c].i_token == MPARM) {
- itemtab[c].i_token = UNDECLARED;
- }
- inmlex = 0;
- #ifdef M_DEBUG
- fprintf(stderr,"exit 'mlex'\n") ;
- #endif
- }
-
-
-
- /*
- * lexical analyser for the arguments of a macro call
- */
- getarg()
- {
- register int c;
- register char *p;
- static int comma;
-
- *tempbuf = 0;
- yylval.cval = tempbuf;
- while(charclass[c = nextchar()] == SPACE);
-
- switch(c) {
-
- case '\0':
- popsi();
- case '\n':
- case ';':
- comma = 0;
- return(skipline(c));
-
- case ',':
- if (comma) {
- comma = 0;
- return(',');
- }
- else {
- comma++;
- return(ARG);
- }
-
- case '\'':
- p = tempbuf;
- do switch (c = nextchar()) {
- case '\0':
- case '\n':
- peekc = c;
- *p = 0;
- err[bflag]++;
- return(ARG);
- case '\'':
- if ((c = nextchar()) != '\'') {
- peekc = c;
- *p = '\0';
- comma++;
- return(ARG);
- }
- default:
- *p++ = c;
- } while (p < tempmax);
- error(symlong);
-
- default: /* unquoted string */
- p = tempbuf;
- peekc = c;
- do switch(c = nextchar()) {
- case '\0':
- case '\n':
- case '\t':
- case ' ':
- case ',':
- peekc = c;
- *p = '\0';
- comma++;
- return(ARG);
- default:
- *p++ = c;
- } while (p < tempmax);
- }
- }
-
-
-
-
-
- /*
- * add a suffix to a string
- */
- suffix(str,suff)
- char *str,*suff;
- {
- while(*str != '\0' && *str != '.')
- *str++;
- strcpy(str, suff);
- }
-
-
-
-
- /*
- * put out a byte to the macro file, keeping the offset
- */
- putm(c)
- char c ;
- {
- mfptr++;
- mfputc(c,mfile) ;
- }
-
-
-
- /*
- * get a byte from the macro file
- */
- getm()
- {
- int ch;
-
- floc++;
- ch = mfgetc(mfile) ;
- if (ch == EOF) {
- ch = 0;
- fprintf(stderr,"bad macro read\n") ;
- }
- return(ch);
- }
-
-
-
- /*
- * pop standard input
- */
- popsi()
- {
- register i;
-
- for (i=0; i<PARMMAX; i++) {
- if (est[i]) free(est[i]);
- }
- floc = est[FLOC];
- free(est);
- expptr--;
- est = expptr ? (char **) expstack[expptr-1] : (char **) 0;
- mfseek(mfile, (long)floc, 0);
- if (lineptr > linebuf) lineptr--;
- }
-
-
-
- /*
- * return a unique name for a local symbol
- * c is the parameter number, n is the macro number.
- */
-
- char *
- getlocal(c, n)
- int c,n;
- {
- static char local_label[10];
- invented++;
- if (c >= 26)
- c += 'a' - '0';
- sprintf(local_label, "?%c%04d", c+'a', n) ;
- return(local_label);
- }
-
-
-
- /*
- * read in a symbol table
- */
- insymtab(name)
- char *name;
- {
- register struct stab *t;
- int s, i, sfile;
-
- t = (struct stab *) tempbuf;
- #ifdef MSDOS
- if ((sfile = open(name, O_RDONLY | O_BINARY)) < 0)
- #else
- if ((sfile = open(name, O_RDONLY)) < 0)
- #endif
- return;
- read(sfile, (char *)t, sizeof *t);
- if (t->t_value != SYMMAJIC)
- return;
-
- s = t->t_token;
- for (i=0; i<s; i++) {
- read(sfile, (char *)t, sizeof *t);
- if (tokenofitem(UNDECLARED) != UNDECLARED)
- continue;
- yylval.itemptr->i_token = t->t_token;
- yylval.itemptr->i_value = t->t_value;
- if (t->t_token == MACRO)
- yylval.itemptr->i_value += mfptr;
- }
-
- while ((s = read(sfile, tempbuf, TEMPBUFSIZE)) > 0) {
- mfptr += s;
- mfwrite(tempbuf, 1, s, mfile) ;
- }
- }
-
-
-
- /*
- * write out symbol table
- */
- outsymtab(name)
- char *name;
- {
- register struct stab *t;
- register struct item *ip;
- int i, sfile;
-
- t = (struct stab *) tempbuf;
- if ((sfile = creat(name, 0644)) < 0)
- return;
- for (ip=itemtab; ip<itemmax; ip++) {
- if (ip->i_token == UNDECLARED) {
- ip->i_token = 0;
- nitems--;
- }
- }
-
- copyname(title, (char *)t);
- t->t_value = SYMMAJIC;
- t->t_token = nitems;
- write(sfile, (char *)t, sizeof *t);
-
- for (ip=itemtab; ip<itemmax; ip++) {
- if (ip->i_token != 0) {
- t->t_token = ip->i_token;
- t->t_value = ip->i_value;
- copyname(ip->i_string, (char *)t);
- write(sfile, (char *)t, sizeof *t);
- }
- }
-
- mfseek(mfile, (long)0, 0);
- while((i = mfread(tempbuf, 1, TEMPBUFSIZE, mfile) ) > 0)
- write(sfile, tempbuf, i);
- }
-
-
-
- /*
- * copy a name into the symbol file
- */
- copyname(st1, st2)
- char *st1, *st2;
- {
- register char *s1, *s2;
- register i;
-
- i = (MAXSYMBOLSIZE+2) & ~01;
- s1 = st1;
- s2 = st2;
-
- while(*s2++ = *s1++) i--;
- while(--i > 0) *s2++ = '\0';
- }
-
- /* get the next source file */
- next_source(sp)
- char *sp ;
- {
-
- if(now_in == NEST_IN -1)
- error("Too many nested includes") ;
- if ((now_file = fopen(sp, "r")) == NULL) {
- char ebuf[100] ;
- sprintf(ebuf,"Can't open include file: %s", sp) ;
- error(ebuf) ;
- }
- if (pass2 && iflist()) {
- lineout() ;
- fprintf(fout, "**** %s ****\n",sp) ;
- }
-
- /* save the list control flag with the current line number */
- if (lstoff)
- linein[now_in] = - linein[now_in] ;
-
- /* no list if include files are turned off */
- lstoff |= iopt ;
-
- /* save the new file descriptor. */
- fin[++now_in] = now_file ;
- /* start with line 0 */
- linein[now_in] = 0 ;
- /* save away the file name */
- src_name[now_in] = malloc(strlen(sp)+1) ;
- strcpy(src_name[now_in],sp) ;
- }
- SHAR_EOF
- if test 50295 -ne "`wc -c < 'zmac.y'`"
- then
- echo shar: error transmitting "'zmac.y'" '(should have been 50295 characters)'
- fi
- chmod +x 'zmac.y'
- fi # end of overwriting check
- echo shar: extracting "'mio.c'" '(2326 characters)'
- if test -f 'mio.c'
- then
- echo shar: will not over-write existing file "'mio.c'"
- else
- cat << \SHAR_EOF > 'mio.c'
- /*
- * mio.c - Colin Kelley 1-18-87
- * routines to emulate temporary file handling with memory instead
- *
- */
-
- #include <stdio.h>
- #define MALLOC_SIZE 10000
-
- unsigned char *malloc(), *realloc();
-
- static unsigned char *mhead; /* pointer to start of malloc()d area */
- static unsigned char *mend; /* pointer to current (just beyond) EOF*/
- static unsigned char *mptr; /* pointer to current position */
- static unsigned int msize; /* size of chunk mhead points to */
-
- FILE *
- mfopen(filename,mode)
- char *filename,*mode;
- {
- if ((mhead = malloc(MALLOC_SIZE)) == 0) {
- msize = 0;
- return (0);
- }
- msize = MALLOC_SIZE;
- mend = mptr = mhead;
- return ((FILE *)1); /* not used */
- }
-
- mfclose(f)
- FILE *f;
- {
- if (mhead) {
- free(mhead);
- return (0);
- }
- else
- return (-1);
- }
-
- unsigned int
- mfputc(c,f)
- unsigned int c;
- FILE *f;
- {
- register unsigned char *p;
- while (mptr >= mhead + msize) {
- if ((p = realloc(mhead,msize+MALLOC_SIZE)) == (unsigned char *)-1) {
- fputs("mio: out of memory\n",stderr);
- return (-1);
- }
- else {
- msize += MALLOC_SIZE;
- mptr = (unsigned char *) (p + (unsigned int)(mptr - mhead));
- mhead = p;
- }
- }
- *mptr = c & 255;
- mend = ++mptr;
- return c;
- }
-
- unsigned int
- mfgetc(f)
- FILE *f;
- {
- if (mptr >= mend) /* no characters left */
- return (-1);
- else
- return (*mptr++);
- }
-
- mfseek(f,loc,origin)
- FILE *f;
- long loc;
- int origin;
- {
- if (origin != 0) {
- fputs("mseek() only implemented with 0 origin",stderr);
- return (-1);
- }
- mptr = mhead + loc;
- return (0);
- }
-
- mfread(ptr, size, nitems,f)
- char *ptr;
- unsigned int size, nitems;
- FILE *f;
- {
- register unsigned int i = 0;
- while (i < nitems) {
- if ((mptr + size) > mend)
- break;
- bcopy(mptr,ptr,size);
- ptr += size;
- mptr += size;
- i++;
- }
- return (i);
- }
-
- mfwrite(ptr, size, nitems, f)
- char *ptr;
- int size, nitems;
- FILE *f;
- {
- register unsigned int i = 0;
- register unsigned char *p;
- while (i < nitems) {
- while (mptr + size >= mhead + msize) {
- if ((p = realloc(mhead,msize+MALLOC_SIZE)) == (unsigned char *)-1){
- fputs("mio: out of memory\n",stderr);
- return (-1);
- }
- else {
- msize += MALLOC_SIZE;
- mptr = (unsigned char *) (p + (unsigned int)(mptr - mhead));
- mhead = p;
- }
- }
- if ((mptr + size) > mhead + msize)
- break;
- bcopy(ptr,mend,size);
- ptr += size;
- mend += size;
- mptr = mend;
- }
- return (i);
- }
- SHAR_EOF
- if test 2326 -ne "`wc -c < 'mio.c'`"
- then
- echo shar: error transmitting "'mio.c'" '(should have been 2326 characters)'
- fi
- chmod +x 'mio.c'
- fi # end of overwriting check
- echo shar: extracting "'zmac.1'" '(1329 characters)'
- if test -f 'zmac.1'
- then
- echo shar: will not over-write existing file "'zmac.1'"
- else
- cat << \SHAR_EOF > 'zmac.1'
- .TH ZMAC l
- .SH NAME
- zmac \- macro cross-assembler for the Zilog Z80 microprocessor
- .SH SYNOPSIS
- zmac [-bdefgilLmnopst] infile
- .SH DESCRIPTION
- The
- .I Zmac
- assembler is modeled after the Intel 8080 macro cross-assembler
- for the Intel 8080 by Ken Borgendale. The major features are: Full
- macro capabilities, Conditional assembly, A very flexible set of
- listing options and pseudo-ops, Symbol table output, Error report,
- Elimination of sequential searching, Commenting of source, Facilities
- for system definiton files.
- .PP
- .I Zmac
- assembles the specified input file (default extension .z) and
- produces a .hex output file. The options are:
- .TP 8
- .B b
- no binary
- .TP 8
- .B d
- debug
- .TP 8
- .B e
- error list only
- .TP 8
- .B f
- print if skipped lines
- .TP 8
- .B g
- do not list extra code
- .TP 8
- .B i
- do not list include files
- .TP 8
- .B l
- no list
- .TP 8
- .B L
- force listing of everything
- .TP 8
- .B m
- print macro expansions
- .TP 8
- .B n
- put line numbers off
- .TP 8
- .B o
- list to standard output
- .TP 8
- .B p
- put out four \\n's for eject
- .TP 8
- .B s
- don't produce a symbol list
- .TP 8
- .B t
- don't know what this option does
- .SH SEE ALSO
- zdis(l)
- .SH FILES
- Source is in /usr/local/src/zmac directory.
- .SH BUGS
- The man page is incomplete. If anyone discovers more information about
- using zmac, please consider helping to update the man page.
- SHAR_EOF
- if test 1329 -ne "`wc -c < 'zmac.1'`"
- then
- echo shar: error transmitting "'zmac.1'" '(should have been 1329 characters)'
- fi
- chmod +x 'zmac.1'
- fi # end of overwriting check
- echo shar: extracting "'zdis.1'" '(526 characters)'
- if test -f 'zdis.1'
- then
- echo shar: will not over-write existing file "'zdis.1'"
- else
- cat << \SHAR_EOF > 'zdis.1'
- .TH ZDIS l
- .SH NAME
- zdis \- disassembler for Z80 cross-assembler
- .SH SYNOPSIS
- zdis < infile.hex
- .SH DESCRIPTION
- .I Zdis
- reads a hex file created by
- .I zmac
- and produces a disassembly on stdout.
- .SH SEE ALSO
- zmac(l)
- .SH FILES
- Source is in /usr/local/src/zmac directory.
- .SH BUGS
- Zdis ignores the program counter field in the hex file. Instead it assumes
- that the hex file has an ORG of 0.
- .sp
- The man page is incomplete. If anyone discovers more information about
- using zdis, please consider helping to update the man page.
- SHAR_EOF
- if test 526 -ne "`wc -c < 'zdis.1'`"
- then
- echo shar: error transmitting "'zdis.1'" '(should have been 526 characters)'
- fi
- chmod +x 'zdis.1'
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-